module TimerCoreLogic (

	input load_flag,
	input [15:0]ResetVal,
	input [15:0]LoadVal,
	input ModeSel,
	input clk,
	input rst_n,
	input StartStop,
	input clk_50Mhz,

	output [7:0] LSBbinaryout,
	output [7:0] MSBbinaryout,
	output [9:0] LED 
);
	
	reg last_StartStop;   
	reg inc_flag;
	reg carry;
	reg time_limit;
	reg last_ModeSel;
	wire [7:0] LSB;
	wire [7:0] MSB;
	wire [15:0] PCoutput = {MSB, LSB};
	wire eq_mode0, eq_mode1;
	wire gt_9999_mode0, lt_9999_mode0;
	wire gt_120_mode1, lt_120_mode1;

	MyComparator16bit cmp_mode0 (
		.A(PCoutput),
		.B(16'd9999),
		.GT(gt_9999_mode0),
		.LT(lt_9999_mode0),
		.EQ(eq_mode0)
	);

	MyComparator16bit cmp_mode1 (
		.A(PCoutput),
		.B(16'd121),
		.GT(gt_120_mode1),
		.LT(lt_120_mode1),
		.EQ(eq_mode1)
	);
	
	wire reach_limit;

	Mux2To1 reach_mux (
		.sel(ModeSel),
		.a(eq_mode0),
		.b(eq_mode1),
		.out(reach_limit)
	);

	ProgramCounter LSB_counter (
		.clk(clk),
		.ResetVal(ResetVal[7:0]),
		.LoadVal(LoadVal[7:0]),
		.reset(~rst_n),
		.load(load_flag),
		.inc(inc_flag),
		.PCoutput(LSB),
		.Mode(ModeSel)
	);

	ProgramCounter MSB_counter (
		.clk(clk),
		.ResetVal(ResetVal[15:8]),
		.LoadVal(LoadVal[15:8]),
		.reset(~rst_n),
		.load(load_flag),
		.inc(carry),
		.PCoutput(MSB),
		.Mode(ModeSel)
	);

	Bit16ToBit8 bit_converter (
		.cnt(PCoutput),
		.Mode(ModeSel),
		.LSBbinaryout(LSBbinaryout),
		.MSBbinaryout(MSBbinaryout)
	);
	
	LEDHandler led_unit(PCoutput, ModeSel, LED);


	always @(posedge clk_50Mhz or negedge rst_n) begin 
		if (~rst_n) begin
			inc_flag <= 1'b0;
			last_StartStop <= 1'b1;
			last_ModeSel <= 1'b0;
			time_limit <= 1'b0;
		end
		else begin
			if (reach_limit)
				time_limit <= 1'b1;

			if (ModeSel != last_ModeSel) begin
				inc_flag <= 1'b0;
				time_limit <= 1'b0;
			end
			else if (~StartStop && last_StartStop && ~time_limit)
				inc_flag <= ~inc_flag;
			else if (reach_limit)
				inc_flag <= 1'b0;

			last_StartStop <= StartStop;
			last_ModeSel <= ModeSel;
		end
	end

	always @(*) begin
		carry = inc_flag & (LSB == 8'd255);
	end
	



endmodule
